Special Datatypes

There are a handful of data types treated in a specific way in PHP; consider the following examples:

Symbols

Symbols are much like strings, in that they are Unicode character sequences. The primary difference is the intended semantics: symbols represent semantic identifiers as opposed to textual literal values. Symbols are case sensitive.

In the text format, symbols are delimited by single-quotes and use the same escape characters.

See Ion Symbols for more details about symbol representations and symbol tables, and our section on Symbols, Tables and Catalogs for a distilled read.

Decimals

See the section on reals for an introduction.


<?php
$d 
= new ion\Decimal(123);
echo 
ion\serialize($d), " = "$d->isInt() ? "int" "noint""\n";
// 123d0 = int

$d = new ion\Decimal("123.123");
echo 
ion\serialize($d), " = "$d->isInt() ? "int" "noint" ,"\n";
// 123.123 = noint

?>

See the official ION spec about real numbers and also Ion Float and Ion Decimals for more notes.

LOBs

BLob

The blob type allows embedding of arbitrary raw binary data. Ion treats such data as a single (though often very large) value. It does no processing of such data other than passing it through intact.

In the text format, blob values are denoted as RFC 4648-compliant Base64 text within two pairs of curly braces.


{{ dHdvIHBhZGRpbmcgY2hhcmFjdGVycw== }}

CLob

The clob type is similar to blob in that it holds uninterpreted binary data. The difference is that the content is expected to be text, so we use a text notation that’s more readable than Base64.


{{ "This is a CLOB of text." }}

See the official ION specification on Blobs and Clobs.

Timestamps

Timestamps represent a specific moment in time, always include a local offset, and are capable of arbitrary precision.

Instances of ion\Timestamp are really just plain \DateTime objects augmented with Stringable and ION specific formatting.


<?=
new ion\Timestamp(
    
precisionion\Timestamp\Precision::FracTZ,

  
  
// 2022-02-25T16:11:54.118+00:00
  
?>

<?=
new ion\Timestamp(
    
precisionion\Timestamp\Precision::Day

  
  
// 2022-02-25T
  
?>

<?=
new ion\Timestamp(
  
precisionion\Timestamp\Precision::MinTZ,
  
formation\Timestamp\Format::Min,
  
datetime"2020-03-15T12:34",
  
timezone: new DateTimeZone("Europe/Vienna")

  
  
// 2020-03-15T12:34+01:00
  
?>

See also the official ION Timestamp specification.

Special PHP Objects

Deprecated Serializable:

NOTE:
The interface Serializable has been deprecated in 8.1 and should be replaced with magic serialize methods.


<?php
  
class srlzbl implements \Serializable {
  private 
$data "foo";
  public function 
serialize() { 
    return 
"bar"
  }
  public function 
unserialize($data) { 
    
$this->data $data
  }
}

$srlzbl = new srlzbl;
var_dump($srlzbl);

$srlzd ion\serialize($srlzbl);
echo 
$srlzd;

/*
    object(srlzbl)#4 (1) {
        ["data":"srlzbl":private]=>
        string(3) "foo"
    }
    
    S::srlzbl::{{"bar"}}

*/

?>

Everything as expected so far, Serializable return a string, but since they cannot indicate whether it's a valid UTF-8 string, a ion\Type::CLob or ion\Type::BLob, CLobs are assumed.

Unserialization does not offer any surprises, either:


<?php 
  
var_dump
(ion\unserialize($srlzd));

/*
  object(srlzbl)#4 (1) {
    ["data":"srlzbl":private]=>
    string(3) "bar"
  }

*/

?>

Magic __serialize:

Implementing serialization behavior with magic methods is the preferred way since 8.1:


<?php
  
class magic {
  private 
string $foo "foo";
  function 
__serialize() : array {
    return [
"foo" => "bar"];
  }
  function 
__unserialize(array $data) : void {
    foreach (
$data as $k => $v
      
$this->$k $v;
  }
}

$magic = new magic;
var_dump($magic);

$srlzd ion\serialize($magic);
echo 
$srlzd;

/*
  object(magic)#6 (1) {
    ["foo":"magic":private]=>
    string(3) "foo"
  }

  O::magic::{foo:"bar"}

*/

?>

Again, unserialization yields the expected results:


<?php
  
var_dump
(ion\unserialize($srlzd));

/*
  object(magic)#7 (1) {
    ["foo":"magic":private]=>
    string(3) "bar"
  }

*/

?>

Custom serialize:

Customly serializable objects work like magic serializable objects, with custom names for the magic methods.


<?php
  
class custom {
  private array 
$data;
  function 
init(array $data) : void {
    
$this->data $data;
  }
  function 
export() : array {
    return 
$this->data;
  }
}

$custom = new custom;
$custom->init(["foo" => "bar"]);
echo 
$srlzd ion\serialize($custom);

/*
    c::custom::{data:p::custom::{foo:"bar"}}
    
*/

?>

The above is actually the result of serializing a standard class backed PHP object, because we didn't implement any serialization primitives and did neither specify a custom method to call. So let's just do that:


<?php
  
$srlzr 
= new ion\Serializer\Serializer(callCustomSerialize"export");
echo 
$srlzd ion\serialize($custom$srlzr);

/*
    C::custom::{foo:"bar"}

*/

?>

Note how this output compares to the output of the standard magic serializable object.

Unserialization works as used to, except sepcifying thwe custom unserialization method to call:


<?php
  
$unsrlzr 
= new ion\Unserializer\Unserializer(callCustomUnserialize"init");
var_dump(ion\unserialize($srlzd$unsrlzr));

/*
    object(custom)#10 (1) {
    ["data":"custom":private]=>
    array(1) {
      ["foo"]=>
      string(3) "bar"
    }
  }

*/

?>

S-Expressions

An S-expression (or symbolic expression) is much like a list in that it’s an ordered collection of values. However, the notation aligns with Lisp syntax to connote use of application semantics like function calls or programming-language statements. As such, correct interpretation requires a higher-level context other than the raw Ion parser and data model.

In the text format, S-expressions are bounded by parentheses. S-expressions also allow unquoted operator symbols (in addition to the unquoted identifier symbols allowed everywhere), so commas are interpreted as values rather than element separators.


null.sexp         // A null S-expression value
()                // An empty expression value
(cons 1 2)        // S-expression of three values
([hello][there])  // S-expression containing two lists

(a+-b)  ( 'a' '+-' 'b' )    // Equivalent; three symbols
(a.b;)  ( 'a' '.' 'b' ';')  // Equivalent; four symbols

Although Ion S-expressions use a syntax similar to Lisp expressions, Ion does not define their interpretation or any semantics at all, beyond the pure sequence-of-values data model indicated above.


Next up